package com.seaboxdata.interfaceJob.queuing;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seaboxdata.entity.queuing.TrafficGetReadTimePayCardInformation;
import com.seaboxdata.kafka.BaseStringKafkaProducer;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Configuration
@Slf4j
/*
 * 实时公交刷卡JOB
 * @Author wei
 * @Date 2021/8/3 15:10
 *
 **/
public class TrafficGetReadTimePayCardInformationJob {

    @Value("${Traffic.TrafficGetReadTimePayCardInformation.url}")
    private String url;

    @Value("${Traffic.busInfo.url}")
    private String busInfoUrl;
    //http://data-sharing.itpd.sibat.cn/open/bus-line-net/api/v1/line/busInfoByEquipmentNo?equipmentNo=217118977&s_key=maweixiong&s_sign=2e2902d3a0c73247a392a57300399ff3&s_time=1610705756

    @Value("${Traffic.busInfo.token}")
    private String busInfoToken;

    @Value("${Traffic.TrafficGetReadTimePayCardInformation.token}")
    private String token;

    @Value("${Traffic.TrafficGetReadTimePayCardInformation.Topic}")
    private String topic;

    @Value("${interface.isTest}")
    private String isTest;
    @Autowired
    private BaseStringKafkaProducer baseStringKafkaProducer;

    /*
     * 每分钟执行,调实时公交接口写入到KAFKA,再循环调用3.4、深圳通设备号查询车辆信息接口.
     * @param
     * @return void
     **/
    @Scheduled(cron = "${Traffic.TrafficGetReadTimePayCardInformation.Scheduled}")//每分钟执行一次
    public void writeKafka() {
        //如果是测试,直接退出
        if ("true".equals(isTest)) {
            return;
        }
        log.info("collect realTimeBusCash begin");
        String dateStr = Long.toString(System.currentTimeMillis() / 1000L);
        String stringToMD5 = stringToMD5(token + dateStr);
        try {
            List<TrafficGetReadTimePayCardInformation> trafficGetReadTimePayCardInformations = new ArrayList<>();
            trafficGetReadTimePayCardInformations = send(url, stringToMD5, dateStr,
                    TrafficGetReadTimePayCardInformation.class);
            if (!CollectionUtils.isEmpty(trafficGetReadTimePayCardInformations)) {
                log.info("realTimeBusCash write kafka,count is {}" + trafficGetReadTimePayCardInformations.size());
                //写入数据到kafka,入库在本地消费
                Date date = new Date();
                for (TrafficGetReadTimePayCardInformation trafficgetreadtimepaycardinformation : trafficGetReadTimePayCardInformations) {
                    trafficgetreadtimepaycardinformation.setCjsj(date);
                    // 调用公交关联车接口
                    String json = doGet(
                            busInfoUrl + "?equipmentNo=" + trafficgetreadtimepaycardinformation.getEquipmentCode(),
                            stringToMD5, dateStr
                    );
                    if (StringUtils.isNotEmpty(json)) {
                        log.info("调用公交关联车接口结果 ->{}", json);
                        Document doc = Document.parse(json.trim());
                        String cardId = null;

                        if (doc.getInteger("status") == 200) {
                            Document data = doc.get("data", Document.class);
                            cardId = data.getString("cardId");
                        }
                        Integer status = doc.getInteger("status");
                        String message = doc.getString("message").replaceAll("\"", "");
                        trafficgetreadtimepaycardinformation.setCardId(cardId);
                        trafficgetreadtimepaycardinformation.setCardStatus(status);
                        trafficgetreadtimepaycardinformation.setMessage(message);
                    } else {
                        log.info("调用公交关联车接口结果失败 ->{}", json);
                    }
                    baseStringKafkaProducer
                            .sendMessageToKafka(JSONObject.toJSONString(trafficgetreadtimepaycardinformation), topic);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有这个md5算法！");
        }
        String md5code = new BigInteger(1, secretBytes).toString(16);
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    /**
     * 发送HTTPGET请求获取接口数据
     *
     * @param url
     * @param token
     * @param time
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public String doGet(String url, String token, String time) throws IOException, URISyntaxException {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 定义请求的参数
        URI uri = new URIBuilder(url).setParameter("s_key", "SZDP").setParameter("s_sign", token)
                .setParameter("s_time", time).build();
        HttpGet httpGet = new HttpGet(uri);
        log.info("GET请求URL ->", uri.getHost() + uri.getPath());
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpGet);
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            log.info("get realTimeBusCash failed {}", e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
            httpclient.close();
        }
        return null;
    }

    public List send(String url, String token, String time, Class<?> cls) throws IOException, URISyntaxException {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 定义请求的参数
        URI uri = new URIBuilder(url).setParameter("s_key", "SZDP").setParameter("s_sign", token)
                .setParameter("s_time", time).build();
        List<Object> results = new ArrayList<>();
        log.info("get realTimeBusCash uri:{}",uri);
        // 创建http GET请求
        HttpGet httpGet = new HttpGet(uri);
        //response 对象
        CloseableHttpResponse response = null;
        try {
            // 执行http get请求
            response = httpclient.execute(httpGet);

            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            JSONArray speeds = null;
            int statusCode = response.getStatusLine().getStatusCode();
            // 判断返回状态是否为200
            log.info(" get realtimepay status {}", statusCode);// 502
            if (statusCode == 200) {
                JSONObject next = (JSONObject) JSONObject.parse(result);
                Object t = next.get("data");
                if ("500".equals(next.getString("status"))) {
                    log.error("get real time pay cash error,response 500");
                    return null;
                }

                if (t instanceof String && StringUtils.isEmpty((String) t)) {
                    log.error("no data");
                    return null;
                }
                speeds = (JSONArray) t;
                Date date = new Date();
                for (int i = 0; i < speeds.size(); i++) {
                    TrafficGetReadTimePayCardInformation trafficGetReadTimePayCardInformation = new TrafficGetReadTimePayCardInformation();
                    JSONArray result1 = (JSONArray) speeds.get(i);
                    trafficGetReadTimePayCardInformation.setCardNumber(result1.get(0).toString());
                    trafficGetReadTimePayCardInformation.setEquipmentCode(result1.get(1).toString());
                    trafficGetReadTimePayCardInformation.setCjsj(date);
                    trafficGetReadTimePayCardInformation
                            .setCashtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(result1.get(2).toString()));
                    trafficGetReadTimePayCardInformation.setCashAmount(Float.valueOf(result1.get(3).toString()));
                    trafficGetReadTimePayCardInformation.setFiled1(result1.get(4).toString());
                    trafficGetReadTimePayCardInformation.setFiled2(result1.get(5).toString());
                    trafficGetReadTimePayCardInformation.setFiled3(result1.get(6).toString());
                    trafficGetReadTimePayCardInformation.setTradeType(Integer.parseInt(result1.get(7).toString()));
                    results.add(trafficGetReadTimePayCardInformation);
                }
            }
        } catch (Exception e) {
            log.error("get realTimeBusCash failed");
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
            httpclient.close();
        }
        return results;
    }


}
